﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.IO.IsolatedStorage;
using System.IO;

using System.ServiceModel;
using System.Device.Location;
using System.Collections;
using Microsoft.Phone.Net.NetworkInformation;
using System.Text.RegularExpressions;

using Microsoft.Phone.Shell;
using Microsoft.Phone.Info;
using ActivityTracker.Library;
using System.Windows.Threading;
using Common.Library;
using OnlineVideos.Services.FileStoreService;
using Microsoft.Live;
using System.Xml.Linq;
using System.Text;
using Microsoft.Live.Controls;
using System.Threading;

using Common.Services;
using System.Diagnostics;

namespace ActivityTracker
{
    public partial class Settings : PhoneApplicationPage
    {
        #region global declaration

        string UserId = "";
        private LiveConnectClient client = null;
        private string skyDriveFolderName = "App_Activity_Tracker";
        SkyDriveBackUpData backup = new SkyDriveBackUpData();
        public static string skyDriveFolderID = string.Empty;
        #endregion

        #region constructor

        public Settings()
        {
            InitializeComponent();
            if (DeviceHelper.GetDeviceUniqueID() != null)
            {
                byte[] id = DeviceHelper.GetDeviceUniqueID();
                UserId = BitConverter.ToString(id);
            }
        }

        #endregion

        #region page events

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                var settings = IsolatedStorageSettings.ApplicationSettings;

                if (settings.Contains("runUnderLock"))
                    lockToggleSwitch.IsChecked = bool.Parse(settings["runUnderLock"].ToString());

                if (settings.Contains("GeoLocationStatus"))
                    GpsLocationToggleSwitch.IsChecked = bool.Parse(settings["GeoLocationStatus"].ToString());

                if (settings.Contains("SendErrors"))
                    EmailErrorsToggleSwitch.IsChecked = bool.Parse(settings["SendErrors"].ToString());
                if (settings.Contains("TipsAndTricks"))
                    TipsTrickssToggleSwitch.IsChecked = bool.Parse(settings["TipsAndTricks"].ToString());

                if (settings.Contains("LocAccuracy"))
                {
                    if (settings["LocAccuracy"].ToString() == "Default")
                        LocAccuracyToggleSwitch.IsChecked = false;
                    else
                        LocAccuracyToggleSwitch.IsChecked = true;
                }
            }
            catch (Exception ex)
            {
                string mess = "Exception in PhoneApplicationPage_Loaded Method In settings file.\n\n" + ex.Message + "\n\n Stack Trace:- " + ex.StackTrace;
                ex.Data.Add("Date", DateTime.Now);
                Exceptions.SaveOrSendExceptions(mess, ex);
            }
        }

        private void EmailErrorsToggleSwitch_Checked(object sender, RoutedEventArgs e)
        {
            try
            {
                SettingsHelper.Save("SendErrors", "true");
                EmailErrorsToggleSwitch.Content = "On";
            }
            catch (Exception ex)
            {
                string mess = "Exception in EmailErrorsToggleSwitch_Checked Method In settings file.\n\n" + ex.Message + "\n\n Stack Trace:- " + ex.StackTrace;
                ex.Data.Add("Date", DateTime.Now);
                Exceptions.SaveOrSendExceptions(mess, ex);
            }
        }

        private void EmailErrorsToggleSwitch_Unchecked(object sender, RoutedEventArgs e)
        {
            try
            {
                SettingsHelper.Save("SendErrors", "false");
                EmailErrorsToggleSwitch.Content = "Off";
            }
            catch (Exception ex)
            {
                string mess = "Exception in EmailErrorsToggleSwitch_Unchecked Method In settings file.\n\n" + ex.Message + "\n\n Stack Trace:- " + ex.StackTrace;
                ex.Data.Add("Date", DateTime.Now);
                Exceptions.SaveOrSendExceptions(mess, ex);
            }
        }

        private void LocAccuracyToggleSwitch_Checked(object sender, RoutedEventArgs e)
        {
            try
            {
                SettingsHelper.Save("LocAccuracy", "High");
                LocAccuracyToggleSwitch.Content = "High";
            }
            catch (Exception ex)
            {
                string mess = "Exception in LocAccuracyToggleSwitch_Checked Method In settings file.\n\n" + ex.Message + "\n\n Stack Trace:- " + ex.StackTrace;
                ex.Data.Add("Date", DateTime.Now);
                Exceptions.SaveOrSendExceptions(mess, ex);
            }
        }

        private void LocAccuracyToggleSwitch_Unchecked(object sender, RoutedEventArgs e)
        {
            try
            {
                SettingsHelper.Save("LocAccuracy", "Default");
                LocAccuracyToggleSwitch.Content = "Default";
            }
            catch (Exception ex)
            {
                string mess = "Exception in LocAccuracyToggleSwitch_Unchecked Method In settings file.\n\n" + ex.Message + "\n\n Stack Trace:- " + ex.StackTrace;
                ex.Data.Add("Date", DateTime.Now);
                Exceptions.SaveOrSendExceptions(mess, ex);
            }
        }

        private void GpsLocationToggleSwitch_Checked(object sender, RoutedEventArgs e)
        {
            try
            {
                GpsLocationToggleSwitch.Content = "On";
                SettingsHelper.Save("GeoLocationStatus", "true");
            }
            catch (Exception ex)
            {
                string mess = "Exception in GpsLocationToggleSwitch_Checked Method In settings file.\n\n" + ex.Message + "\n\n Stack Trace:- " + ex.StackTrace;
                ex.Data.Add("Date", DateTime.Now);
                Exceptions.SaveOrSendExceptions(mess, ex);
            }
        }

        private void GpsLocationToggleSwitch_Unchecked(object sender, RoutedEventArgs e)
        {
            try
            {
                GpsLocationToggleSwitch.Content = "Off";
                SettingsHelper.Save("GeoLocationStatus", "false");
                lockToggleSwitch.Content = "Off";
                SettingsHelper.Save("runUnderLock", "false");
                lockToggleSwitch.IsChecked = false;
            }
            catch (Exception ex)
            {
                string mess = "Exception in GpsLocationToggleSwitch_Unchecked Method In settings file.\n\n" + ex.Message + "\n\n Stack Trace:- " + ex.StackTrace;
                ex.Data.Add("Date", DateTime.Now);
                Exceptions.SaveOrSendExceptions(mess, ex);
            }
        }

        private void HelpImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Views/Help/Help.xaml?id=9&url=eatEb20PFaw", UriKind.Relative));
        }

        private void LocationHelpImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Views/Help/Help.xaml?id=10&url=WVyXCA5brTI", UriKind.Relative));
        }

        #endregion

        #region Data Backup

        private void btnBackup_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (client == null || client.Session == null)
                {
                    stklogin.Visibility = Visibility.Visible;
                    stkmessage.Visibility = Visibility.Visible;
                    stkrestore.Visibility = Visibility.Collapsed;
                    stkbackup.Visibility = Visibility.Collapsed;
                }
                else
                {
                    btnBackup.IsEnabled = false;
                    BackupActivities();
                }
            }
            catch (Exception ex)
            {
                string mess = "Exception in btnBackup_Click Method In Settings file.\n\n" + ex.Message + "\n\n Stack Trace:- " + ex.StackTrace;
                ex.Data.Add("Date", DateTime.Now);
                Exceptions.SaveOrSendExceptions(mess, ex);
            }
        }

        private void BackupActivities()
        {
            try
            {
                if (NetworkHelper.IsNetworkAvailable())
                {
                    client.GetCompleted += new EventHandler<LiveOperationCompletedEventArgs>(client_GetCompleted);
                    client.GetAsync("me/skydrive/files?filter=folders,albums");
                }
                else
                {
                    // btnBackup.IsEnabled = true;
                    MessageBox.Show("Data Connection not available");
                }
            }
            catch (Exception ex)
            {
                Exception exnew = new Exception("Exception in BackupActivities Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }

        void client_GetCompleted(object sender, LiveOperationCompletedEventArgs e)
        {
            try
            {
                client.GetCompleted -= this.client_GetCompleted;
                if (e.Error == null)
                {
                    Dictionary<string, object> folderData = (Dictionary<string, object>)e.Result;
                    List<object> folders = (List<object>)folderData["data"];

                    foreach (object item in folders)
                    {
                        Dictionary<string, object> folder = (Dictionary<string, object>)item;
                        if (folder["name"].ToString() == skyDriveFolderName)
                            skyDriveFolderID = folder["id"].ToString();
                    }

                    if (skyDriveFolderID == string.Empty)
                    {
                        Dictionary<string, object> skyDriveFolderData = new Dictionary<string, object>();
                        skyDriveFolderData.Add("name", skyDriveFolderName);
                        //You can add a folder description, but for some reason it does not work.
                        //folderData.Add("description", "Folder for storing files from my WP7 app isolated storage.");
                        client.PostCompleted += new EventHandler<LiveOperationCompletedEventArgs>(CreateFolder_Completed);
                        client.PostAsync("me/skydrive", skyDriveFolderData);
                    }
                    else
                        CreateFileInIsoStore(skyDriveFolderID);
                }
                else
                {
                    MessageBox.Show(e.Error.Message);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Some data not backup, please try again later");
                Exception exnew = new Exception("Exception in backup Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }

        void CreateFolder_Completed(object sender, LiveOperationCompletedEventArgs e)
        {
            client.PostCompleted -= this.CreateFolder_Completed;
            try
            {
                if (e.Error == null)
                {
                    Dictionary<string, object> folder = (Dictionary<string, object>)e.Result;
                    skyDriveFolderID = folder["id"].ToString();
                    CreateFileInIsoStore(skyDriveFolderID);
                }
                else
                {
                    MessageBox.Show(e.Error.Message);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Some data not backup, please try again later");
                Exception exnew = new Exception("Exception in backup Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }
        private void CreateFileInIsoStore(string skyDriveFolderID)
        {
            try
            {
                FileSpliting bd = new FileSpliting();
                List<FileEntity> list = new List<FileEntity>();
             
                list = bd.BackUpdataUsingFileSplitting(UserId);

                ThreadPool.QueueUserWorkItem(func =>
                {
                    foreach (FileEntity item in list)
                    {

                        backup.Uploaddata(item.FileName, item.Stream, skyDriveFolderID,client); //you need to call this on a separate thread or it will lock the ui thread.                       
                    }
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        btnBackup.IsEnabled = true;
                        MessageBox.Show("All data Saved Successfully");
                    });    //your button click method is now also asynchronous
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show("Some data not backup, please try again later");
                Exception exnew = new Exception("Exception in backup Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }

        #endregion

        #region Data Restore

        private void btnRestore_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (client == null || client.Session == null)
                {
                    stklogin.Visibility = Visibility.Visible;
                    stkbackup.Visibility = Visibility.Collapsed;
                    stkrestore.Visibility = Visibility.Collapsed;
                    stkmessage.Visibility = Visibility.Visible;
                    //  MessageBox.Show("You must sign in first.");
                }
                else
                {
                     btnRestore.IsEnabled = false;
                    RestoreActivities();
                }
            }
            catch (Exception ex)
            {
                string mess = "Exception in btnRestore_Click Method In Settings file.\n\n" + ex.Message + "\n\n Stack Trace:- " + ex.StackTrace;
                Exceptions.SaveOrSendExceptions(mess, ex);
            }
        }

        private void RestoreActivities()
        {
            try
            {
                SkyDriveRestoreData rd = new SkyDriveRestoreData();
                if (NetworkHelper.IsNetworkAvailable())
                {
                    rd.GetFolderId(skyDriveFolderName, client, UserId,btnRestore);
                }
                else
                {
                    btnRestore.IsEnabled = true;
                    MessageBox.Show("Cellular Network not available");
                }
            }
            catch (Exception ex)
            {
                Exception exnew = new Exception("Exception in RestoreActivities Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }

        #endregion

        #region Run under lock

        private void lockToggleSwitch_Checked(object sender, RoutedEventArgs e)
        {
            bool IsLocationTrackingEnable = SettingsHelper.getBoolValue("GeoLocationStatus");

            if (IsLocationTrackingEnable)
            {
                if (!ApplicationIdleModeHelper.Current.HasUserAgreedToRunUnderLock)
                {
                    MessageBoxResult result = MessageBox.Show("Running under lockscreen can consume battery even when screen is locked and you are not using the application. Click OK to enable", "", MessageBoxButton.OKCancel);
                    if (result == MessageBoxResult.OK)
                    {
                        ApplicationIdleModeHelper.Current.HasUserAgreedToRunUnderLock = true;
                        lockToggleSwitch.Content = "On";
                        SettingsHelper.Save("runUnderLock", "true");
                    }
                    else
                    {
                        //MessageBox.Show("Run under lock state was not changed");
                        lockToggleSwitch.IsChecked = false;
                        SettingsHelper.Save("runUnderLock", "false");
                    }
                }
                else
                {
                    lockToggleSwitch.Content = "On";
                    SettingsHelper.Save("runUnderLock", "true");
                }
            }
            else
            {
                MessageBox.Show("Location tracking must be enabled");
                lockToggleSwitch.IsChecked = false;
            }
        }

        private void lockToggleSwitch_Unchecked(object sender, RoutedEventArgs e)
        {
            lockToggleSwitch.Content = "Off";
            SettingsHelper.Save("runUnderLock", "false");
        }

        #endregion

        #region Tips and Tricks

        private void TrickandTricksToggleSwitch_Unchecked(object sender, RoutedEventArgs e)
        {
            SettingsHelper.Save("TipsAndTricks", "false");
            TipsTrickssToggleSwitch.Content = "Off";

        }

        private void TrickandTricksToggleSwitch_Checked(object sender, RoutedEventArgs e)
        {
            SettingsHelper.Save("TipsAndTricks", "true");
            TipsTrickssToggleSwitch.Content = "On";

        }

        #endregion

        private void OnSessionChanged(object sender, LiveConnectSessionChangedEventArgs e)
        {
            if (e.Session != null)
            {
                client = new LiveConnectClient(e.Session);
                stklogin.Visibility = Visibility.Collapsed;
                stkrestore.Visibility = Visibility.Visible;
                stkbackup.Visibility = Visibility.Visible;
                stkmessage.Visibility = Visibility.Collapsed;
            }
            else
            {
                //stklogin.Visibility = Visibility.Visible;
                //stkrestore.Visibility = Visibility.Collapsed;
                //stkbackup.Visibility = Visibility.Collapsed;
                // MessageBox.Show("Not signed in.");
                client = null;
            }
        }
    }
}